/**
 * Copyright (c) [2025] [何屹林]
 *
 * 保留所有权利。
 *
 * 文件名称：utils.h
 * 模块功能说明：
 * 该模块作为基本类型定义、基本内容引入、基本模块实现，构建了基础的定义，包含了各类杂项
 *
 * 华南师范大学-计算机学院-网络工程-1班
 * 作者：何屹林-20222132023
 * 完成日期：2025年7月24日
 */
#ifndef UTILS_H
#define UTILS_H

#include <QString>
#include <QStringList>
#include <QSet>
#include <QMessageBox>
#include <QMap>
#include <QVector>
#include <QUrl>
#include <QString>
#include <QFile>
#include <QFileDialog>
#include <QTextStream>
#include <QMetaEnum>
#include <QMimeData>
#include <QDebug>
#include <QStandardPaths>
#include <QStack>
#include <QChar>
#include <QMapData>
#include <QMapIterator>
#include <QVectorIterator>
#include <QListIterator>
#include <QList>
#include <QProcess>
#include <QRegularExpression>
#include <QStandardItemModel>

#include <stdio.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

#include "form.h"

//退出标志，加在需要编码的单词后面
#define EXIT char(-1)
//任意符号
#define ANY '~'
//终结符
#define END '$'
//范围运算符号
#define RANGE '-'
//空字符
#define EMPTY char(0)

//char转string，便于输出表格时使用
#define STR(x) QString(1,x)

QString trim(QString str);

QString set2string(const QSet<int>&s);

QVector<QVector<QChar>> sortCharSet(const QSet<QChar>& s);

QString escape(const QChar&c);





typedef struct SyntaxNode {//句法结点
    QString nodeStr;
    QVector<SyntaxNode *> children;

    explicit SyntaxNode(const QString& str) : nodeStr(str) {}
    ~SyntaxNode() {
        qDeleteAll(children);  // 自动清理子节点
    }

    // 添加子节点
    void addChild(SyntaxNode* child) {
        children.append(child);
    }

    SyntaxNode(): SyntaxNode("") {}
}SyntaxNode, * SyntaxTree;


struct Gram {//规则结点简化
    QString l;
    QStringList r;
    Gram(QString a,QStringList b):l(a),r(b){}
};


// 分析表结点
typedef struct LR1_table_item {
    int kind;   // 1 表示移进、2 表示规约、3 表示非终结符移进、4 表示接受
    int idx;

    QString toStr(){
        QString str;
        switch(kind){
        case 1:
        {str+='S';break;}
        case 2:
        {str+='R';break;}
        case 3: break;
        case 4: str+="ACC";break;
        }
        if(idx) str+=QString::number(idx);
        return str;
    }
    LR1_table_item():kind(0),idx(-1){};
}LR1TableItem;

struct Lex {//lex文件结点
    std::string kind,value;
};

//单个规则
typedef struct Item {
    QString name;       //非终结符名字
    QStringList rule;   //右侧表达式
    QSet<QString> next; //在lr（0)中没有用到，是lr（1）用来构造dfa前的先行符号，考虑归约就看next
    int pos;            //第几个表达式

    Item(QString n,QStringList r,QSet<QString> s,int p):name(n),rule(r),next(s),pos(p){};
    Item(){};
    static bool haveSameCore(Item i, Item j);

    friend bool operator==(const Item a, const Item b) {//用于hash
        return a.name == b.name && a.rule == b.rule && a.next == b.next && a.pos == b.pos;
    }

    friend bool operator<(const Item a, const Item b) {//用于set排序
        if (a.name == b.name) {
            if (a.rule == b.rule) {
                if (a.pos == b.pos) {
                    return a.pos < b.pos;
                }
                return a.pos < b.pos;
            }
            return a.rule < b.rule;
        }
        return a.name < b.name;
    }
}item;

size_t qHash(const Item& key);              //规则表



#endif // UTILS_H
